import clr
clr.AddReference("System.Core")
clr.AddReference("HDCDataAccess_dotnetfx35")
clr.AddReference("System.Data.Entity")
import System
import time
from System.Linq import Enumerable
from uk.ac.soton.ses.DAL import MaterialsMetadataContext,ExperimentDataFile,Experiment
from uk.ac.soton.ses import HDCConfiguration

entity_connection_string = HDCConfiguration.Instance.ConfigurationOptions.DatabaseOptions.EntityConnectionString

with MaterialsMetadataContext(entity_connection_string) as dbcontext:

    # =======
    # Copy parameters between datasets
    dataset16 = dbcontext.GetExperimentByID(16)
    dataset291 = dbcontext.GetExperimentByID(291)
    #dataset291.CopyParametersToExperiment(dataset16, copySystem=False, dbcontext=dbcontext)
    # =======


    # =======
    # Print parameters for all datasets in collection 1
    # Define a function to recurse through nested parameters
    def print_parameter_tree(parameters,level):
        prefix = "\t"
        for i in range(0, level):
            prefix = prefix + "\t"
        for p in parameters:
            print prefix + p.Name, ":", p.Value
            child_parameters = p.GetChildParameters()
            if child_parameters.Count > 0:
                print_parameter_tree(child_parameters,level + 1)

    # Retrieve datasets from collection 1
    datasets = dbcontext.GetExperimentsByCollectionID(collectionID=1, includeDeleted=False)
    # Print info from all datasets
    for ds in datasets:
        print "Dataset: ", ds.Name
        parameters = dbcontext.GetExperimentTopLevelParameters(ds.ID, includeSystem=False, parameterName=None)
        print_parameter_tree(parameters, 0)
    # =======

        
    # =======
    # Find datasets with a specific property
    datasets = dbcontext.GetExperimentsWithMatchingParameter("Crystal system", "triclinic")
    # Convert it to an array
    datasets_array = Enumerable.ToArray[Experiment](datasets)
    # Loop around the matching datasets
    for ds in datasets_array:
        visitedparameter = ds.LookupParameter("Test script executed date")
        # Check if we've visited this dataset before
        if visitedparameter is None:
            # Perform some action on the dataset
            print ds.ID, ds.Name, "-",  ds.GetUNCPath(dbcontext), ds.GetDetailsWebPage(dbcontext)
            # Record that we have visited this dataset
            #ds.SaveParameterValue(dbcontext, "Test script executed date", time.strftime("%c"), create=True)
            #dbcontext.SaveChanges()
    # =======


    # =======
    # Find recommended datasets related to dataset 16, list some information and create a link to them
    related_datasets = dbcontext.GetRelatedExperiments(dataset16.ID, count=5, findDeleted=False)
    print "Related datasets:"
    for ds in related_datasets:
        # Print dataset information, the dataset's UNC path and the dataset's web page
        print ds.ID, ds.Name, "-",  ds.GetUNCPath(dbcontext), ds.GetDetailsWebPage(dbcontext)
        # Link dataset 16 to recommended dataset
        #dbcontext.CreateExperimentLink(dataset16.ID, ds.ID, saveChanges=True)
    # =======
    

print "Finished."
System.Console.ReadLine()


#from System.Linq.Expressions import Expression
#from System.Linq import Queryable
#clr.ImportExtensions(System.Linq)

    #w = clr.GetClrType(System.Linq.Queryable).GetMethod("Where", System.Array[System.Type]([type(System.Linq.IQueryable[Experiment]),type(Expression[Func[Experiment,bool]])]))
    #datafiles = w.Invoke(dbcontext.ExperimentDataFiles,lambda f: f.Filename == "file.xtekct")
    #datafiles = Queryable.Where[ExperimentDataFile](dbcontext.ExperimentDataFiles,Expression(Func[ExperimentDataFile,bool](x)))
    #method = clr.GetClrType(MaterialsMetadataContext).GetMethod("GetExperimentTopLevelParameters")#, System.Array[System.Type]([type(int),type(bool), type(str)]))
    #parameters = method.Invoke(dbcontext,System.Array[object]([16,False,None]))
